package com.zhengxiang.onlinexamination.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhengxiang.onlinexamination.dao.*;
import com.zhengxiang.onlinexamination.entity.*;
import com.zhengxiang.onlinexamination.entity.vo.WaitPaperVo;
import com.zhengxiang.onlinexamination.service.SettingService;
import com.zhengxiang.onlinexamination.service.WaitPaperService;
import com.zhengxiang.onlinexamination.service.WaitPaperUserService;
import com.zhengxiang.onlinexamination.utils.QRCodeUtil;
import com.zhengxiang.onlinexamination.utils.SecurityUtils;
import com.zhengxiang.onlinexamination.utils.WxUtils;
import com.zhengxiang.onlinexamination.utils.oss.OSSUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 待考试(WaitPaper)表服务实现类
 *
 * @author
 * @since 2023-03-15 11:44:51
 */
@Transactional(rollbackFor = Exception.class)
@Service("waitPaperService")
public class WaitPaperServiceImpl extends ServiceImpl<WaitPaperMapper, WaitPaper> implements WaitPaperService {
    @Resource
    private WaitPaperMapper waitPaperMapper;

    @Resource
    private ExamPaperMapper examPaperMapper;

    @Resource
    private WaitPaperUserService waitPaperUserService;

    @Autowired
    private SettingService settingService;

    @Resource
    private PreviewPaperMapper previewPaperMapper;

    @Resource
    private CustomerUserDao customerUserDao;

    @Override
    public void saveWaitPaper(WaitPaperVo wp) throws IOException {
        //获取试卷内容
        ExamPaper examPaper = examPaperMapper.queryById(wp.getExamPaperId());
        wp.setPaperContent(JSONObject.toJSONString(examPaper));
        wp.setWaitTime(examPaper.getExamEndTime());
        waitPaperMapper.insert(wp);
//        生成二维码
        createQr(wp);
        //为每个人创建一条待考记录关系
        List<WaitPaperUser> waitPaperUsers = new ArrayList<>();
        wp.getUserIds().forEach(s -> {
            WaitPaperUser wpu = new WaitPaperUser();
            wpu.setUserId(s);
            wpu.setWaitPaperId(wp.getWaitPaperId());
            waitPaperUsers.add(wpu);
        });
        waitPaperUserService.saveBatch(waitPaperUsers);


    }

    //生成二维码地址,扫码入场考试
    public void createQr(WaitPaper wp) throws IOException {
        StringBuffer params = new StringBuffer();
        params.append("waitPaperId=").append(wp.getWaitPaperId());
        InputStream wxQr = WxUtils.getWxQr(params.toString(), WxUtils.getWxToken(), "pages/syudy/scanAnswer/index");
        BufferedImage image = ImageIO.read(wxQr);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, "png", os);
        InputStream is = new ByteArrayInputStream(os.toByteArray());
        String bucketName = settingService.querySetting(3, 3).getSetVal();
        String today = DateUtil.today();
        String onlyId = IdUtil.createSnowflake(1, 1).nextIdStr();
        String qrCodeName = today + "/" + onlyId + ".png";
        OSSUtils.putObject(is, qrCodeName, bucketName);
        String codeUrl = OSSUtils.getObjectUrl(bucketName, qrCodeName);
        wp.setQrCode(codeUrl);
        waitPaperMapper.updateById(wp);

    }

    public void formatContent(ExamPaper examPaper) {
        List<Integer> correctQuAnswerId = new ArrayList<>();
        JSONObject jsonObject = new JSONObject();
        List<PaperQu> paperQus = examPaper.getPaperQus();
        for (PaperQu pq : paperQus) {
            Qu qu = pq.getQu();
            List<QuAnswer> quAnswers = qu.getQuAnswers();
            for (QuAnswer qa : quAnswers) {
                if (qa.getAnswerCorrect() == 1) {
                    correctQuAnswerId.add(qa.getQuAnswerId());
                }
            }
        }
        //本场试卷正确答案，用于优化后期打分
        jsonObject.put("correctQuAnswerId", correctQuAnswerId);
        jsonObject.put("examPaper", examPaper);


    }

    @Override
    public IPage<WaitPaper> queryAll(WaitPaperVo wp) {
        QueryWrapper<WaitPaper> q = new QueryWrapper<>();
        q.lambda().select(WaitPaper::getWaitPaperId, WaitPaper::getExamPaperId,
                WaitPaper::getPaperName, WaitPaper::getWaitUserNum,
                WaitPaper::getWaitTime, WaitPaper::getQrCode, WaitPaper::getAlreadyUserNum,
                WaitPaper::getWaitState, WaitPaper::getWaitTime, WaitPaper::getCreateTime);
        if (StringUtils.isNotEmpty(wp.getPaperName())) {
            q.lambda().like(WaitPaper::getPaperName, wp.getPaperName());
        }
        q.lambda().orderByDesc(WaitPaper::getCreateTime);
        return waitPaperMapper.selectPage(new Page<>(wp.getCurrent(), wp.getSize()), q);
    }

    @Override
    public void updateWaitState(WaitPaperVo wp) {
        waitPaperMapper.updateById(wp);
    }

    @Override
    public WaitPaperVo queryPaperInfo(WaitPaperVo wp) {
        QueryWrapper<WaitPaper> wpWrapper = new QueryWrapper<>();
        wpWrapper.lambda().eq(WaitPaper::getWaitPaperId, wp.getWaitPaperId());
        WaitPaper waitPaper = waitPaperMapper.selectOne(wpWrapper);
        WaitPaperVo waitPaperVo = new WaitPaperVo();
        ExamPaper examPaper = examPaperMapper.queryById(waitPaper.getExamPaperId());
        List<Qu> radioList = new ArrayList<>();
        List<Qu> multiList = new ArrayList<>();
        List<Qu> judgeList = new ArrayList<>();
        List<Qu> shortAnswerList = new ArrayList<>();
        examPaper.getPaperQus().forEach(paperQu -> {
            Qu qu = paperQu.getQu();
            switch (qu.getQuType()) {
                case 1:
                    radioList.add(qu);
                    break;
                case 2:
                    multiList.add(qu);
                    break;
                case 3:
                    judgeList.add(qu);
                    break;
                case 4:
                    shortAnswerList.add(qu);
                    break;
                default:
                    break;
            }
        });
        BeanUtil.copyProperties(waitPaper, waitPaperVo);
        waitPaperVo.setWaitPaperId(wp.getWaitPaperId());
        waitPaperVo.setRadioList(radioList);
        waitPaperVo.setMultiList(multiList);
        waitPaperVo.setJudgeList(judgeList);
        waitPaperVo.setShortAnswerList(shortAnswerList);
        waitPaperVo.setExamPaper(examPaper);

        return waitPaperVo;
    }


    @Override
    public boolean checkWaitPaper(Integer userId, Integer waitPaperId) {
        QueryWrapper<WaitPaperUser> wuqWrapper = new QueryWrapper<>();
        wuqWrapper.lambda().eq(WaitPaperUser::getUserId, userId).eq(WaitPaperUser::getWaitPaperId, waitPaperId).eq(WaitPaperUser::getWaitPaperState, 0);
        WaitPaperUser wp = waitPaperUserService.getOne(wuqWrapper);
        if (Objects.isNull(wp)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public IPage queryWaitPaperByUser(Page page) {
        CustomerUser customerLoginUser = SecurityUtils.getCustomerLoginUser();
        return waitPaperMapper.queryWaitPaperByUser(page, customerLoginUser.getCustomerUserId());
    }
}
